package com.myk.game.gobangchess.rooms.oldrooms;

import com.myk.game.gobangchess.*;
import com.myk.game.gobangchess.constants.WinMode;
import com.myk.game.gobangchess.signs.*;
import com.myk.game.gobangchess.utils.GridsUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 《夺势棋》
 * 9x9大小的棋盘，双方各有9枚棋子。
 * 棋子都有四个属性：左上角是生命值4-6，右上角是攻击距离1-3，右边是攻击力1-3，下边是移动速度1-3。先后手的棋子属性有些不一样以平衡先后手。
 * 黑先白后双方轮流行动。
 * 每回合开始时，只要己方棋槽有棋子，就要选择一个放到场上任意空位。开局落下的第一枚棋子要标记为“星”。
 * 然后除刚落下的棋子外，让己方场上所有棋子移动或攻击一次。
 * 棋子移动不能超过自身的移动速度，且只能直向一格一格的移动，不能移动到已有棋子的格子上，可以停留在原地。
 * 棋子攻击只能选中攻击距离范围内的敌方棋子，直向一格一格计算距离，路径上不能有阻碍。
 * 攻击敌方棋子时目标棋子生命值减少自攻击棋子的攻击力，当目标棋子生命值降低到0时，俘虏目标棋子，将目标棋子从场上移动到己方棋槽。
 * 每次开始前所有棋子生命值恢复满额。
 * 吃到对方场上和棋槽里只剩4枚棋子时获胜，吃掉对方标记为“星”的棋子时也直接获胜。
 */
public class SeizePowerChessRoom extends Room {

    private Sider blackSider; //黑方先手方游戏状态与数据
    private Sider whiteSider; //白方后手方游戏状态与数据
    private List<Sign> chessboardStyle; //不变的棋盘样式
    private List<Chess> chessList; //场上棋子集合
    private Chess choose; //当前选中的棋子

    public SeizePowerChessRoom(String roomName) {
        super(roomName, "\t\t轮流先落1子，再让场上其它棋子移动或攻击1次。棋上数字左上为hp、右上rang、右atk，下sp。攻击至hp低于0可俘虏棋子。俘虏对方5枚棋子或标星棋子获胜。", "夺势棋",Sider.SEIZE_POWER_CHESS_STYLE, true, true);
        Sider.initChessBoardStyle(this); //初始棋盘样式
    }

    @Override
    protected void onStartPrepare() {
        initSiders();//游戏开始的时候初始化棋子和布局
        //黑方先手行动，黑方先落子，白方等待
        blackSider.switchPutState();
        whiteSider.switchWaitState();
        noticeBlackMove();
    }

    @Override
    public void resetGrids() {
        step = 0;
        gameTip = "-1";
        curGrids = GridsUtils.copyGrids(originGrids);
        signList.clear();
        chessList = null;
        choose = null;
    }

    @Override
    public void doRule(int row, int col, int value) {
        Sider curSider = getCurSider(); //获取当前行动方
        if (curSider == null) {
            return;
        }
        Chess chess = getChessByPos(row, col); //获取触摸到的棋子？（可能为空）
        if (choose == null) {//若当前未选中棋子
            //选择棋子
            if (chess != null && !chess.isActioned) {
                choose = chess;
                noticeAllRefreshGameInfo();
            }
        }
        else {//若当前已经选中棋子了
            if (chess != null && !chess.isActioned) {//又选中了一个可以选的
                if (!curSider.isChessInSlot(chess) && choose == chess) { //如果点的是棋盘上的棋且留在原位置
                    curSider.moveChess(row, col); //尝试移动，这里是选中棋子停留在原位，方法里支持留在原位置的逻辑
                }
                else {
                    //切换选择棋子
                    choose = chess;
                    noticeAllRefreshGameInfo();
                }
            }
            else {
                if (chess != null) {
                    if (!curSider.isChessInSlot(chess) && chess.side != choose.side) { //选中了对方场上棋子时
                        curSider.attackChess(chess); //尝试攻击目标棋子
                    }
                }
                else {
                    curSider.moveChess(row, col); //尝试摆放或者移动到空格
                }
            }
        }
    }

    @Override
    public String getRuleText() {
        return "《夺势棋》\n" +
                " * 9x9大小的棋盘，双方各有9枚棋子。\n" +
                " * 棋子都有四个属性：左上角是生命值4-6，右上角是攻击距离1-3，右边是攻击力1-3，下边是移动速度1-3。先后手的棋子属性有些不一样以平衡先后手。\n" +
                " * 黑先白后双方轮流行动。\n" +
                " * 每回合开始时，只要己方棋槽有棋子，就要选择一个放到场上任意空位。开局落下的第一枚棋子要标记为“星”。\n" +
                " * 然后除刚落下的棋子外，让己方场上所有棋子移动或攻击一次。\n" +
                " * 棋子移动不能超过自身的移动速度，且只能直向一格一格的移动，不能移动到已有棋子的格子上，可以停留在原地。\n" +
                " * 棋子攻击只能选中攻击距离范围内的敌方棋子，直向一格一格计算距离，路径上不能有阻碍。\n" +
                " * 攻击敌方棋子时目标棋子生命值减少自攻击棋子的攻击力，当目标棋子生命值降低到0时，俘虏目标棋子，将目标棋子从场上移动到己方棋槽。\n" +
                " * 每次开始前所有棋子生命值恢复满额。\n" +
                " * 吃到对方场上和棋槽里只剩4枚棋子时获胜，吃掉对方标记为“星”的棋子时也直接获胜。";
    }

    @Override
    public String getGameInfo() {
        //先全部初始化
        curGrids = GridsUtils.copyGrids(originGrids);
        signList.clear();
        signList.addAll(chessboardStyle);

        //根据chessList集合和choose对象来生成要显示到客户端的布局和标记
        if (chessList != null && chessList.size() > 0) {
            //绘制棋子
            for (Chess chess : chessList) {
                curGrids[chess.row][chess.col] = chess.side.side; //显示棋子的底座
                signList.add(new BadgeSign(getIndex(chess.row, chess.col), String.valueOf(chess.hp), 0, chess.hp == chess.maxHp ? "#FF000000" : "#FFFF3333", "#FFEB859E"));
                signList.add(new BadgeSign(getIndex(chess.row, chess.col), String.valueOf(chess.rng), 2, "#FF000000", "#FF7F7EF7"));
                signList.add(new BadgeSign(getIndex(chess.row, chess.col), String.valueOf(chess.atk), 5, "#FF000000", "#FFF7CF89"));
                signList.add(new BadgeSign(getIndex(chess.row, chess.col), String.valueOf(chess.sp), 7, "#FF000000", "#FF9EFCC2"));
                if (chess.isStar) { //绘制标星
                    signList.add(new TextSign(getIndex(chess.row, chess.col), "※", "#FFEC6B30"));
                }
                if (!chess.isActioned) {//未行动过的棋子显示绿色框
                    signList.add(new AroundSign(getIndex(chess.row, chess.col), "#00FFFFFF", "#FF33CC33", 1.3f));
                }
            }
            //绘制选中状态
            if (choose != null) {
                //被选中的棋子显示紫色框
                signList.add(new AroundSign(getIndex(choose.row, choose.col), "#00FFFFFF", "#FFFFAA33", 1.3f));
                //半透明绿色为可移动的路径
                List<int[]> canMovedPosList = choose.getCanMovedPos(); //获取该棋子可移动到的格子的坐标集合
                if (canMovedPosList != null && canMovedPosList.size() > 0) {
                    List<Integer> ids = new ArrayList<>();
                    for (int[] canMovedPos : canMovedPosList) {
                        ids.add(getIndex(canMovedPos[0], canMovedPos[1]));
                    }
                    signList.add(new ColorSign(ids, "#66339933")); //可移动到的格子用更淡的绿色表示
                }
                //半透明黄色为可攻击的格子
                List<int[]> canAttackPosList = choose.getCanAttackPos(); //获取该棋子可攻击到的格子的坐标集合
                if (canAttackPosList != null && canAttackPosList.size() > 0) {
                    List<Integer> ids = new ArrayList<>();
                    for (int[] canAttackPos : canAttackPosList) {
                        ids.add(getIndex(canAttackPos[0], canAttackPos[1]));
                    }
                    signList.add(new ColorSign(ids, "#66DDDD33")); //可移动到的格子用更淡的黄色表示
                }
            }
        }
        return super.getGameInfo();
    }

    @Override
    public String getCoordMode() {
        return "31001100";
    }

    //游戏获胜
    private void gameOver(Sider sider) {
        if (sider.side == 1){
            doOver(WinMode.BLACK_WIN,player_black.getNickNameOrTemp() + "执黑获胜！" );
        }
        else {
            doOver(WinMode.WHITE_WIN,player_white.getNickNameOrTemp() + "执白获胜！" );
        }
    }

    //初始化对弈双方的元数据
    private void initSiders() {
        blackSider = new Sider(this, 1);
        whiteSider = new Sider(this, 2);
        chessList = new ArrayList<>();
        choose = null;
        Sider.initChesses(this); //初始创建和摆放棋子到棋槽中
    }

    //获取当前行动方
    private Sider getCurSider() {
        if (cur == 1) {
            return blackSider;
        }
        else if (cur == 2) {
            return whiteSider;
        }
        else {
            return null;
        }
    }

    //获取下一个行动方
    private Sider getOtherSider() {
        if (cur == 1) {
            return whiteSider;
        }
        else if (cur == 2) {
            return blackSider;
        }
        else {
            return null;
        }
    }

    //切换行动方
    private void changeSider() {
        stepAdd();; //增加步数避免意外重置棋盘
        for (Chess chess : chessList) {
            chess.hp = chess.maxHp; //交换行动时所有棋子hp恢复满
        }
        if (cur == 1) {
            blackSider.switchWaitState();
            if (whiteSider.getSlotChesses().size() > 0) {
                whiteSider.switchPutState();
            }
            else {
                whiteSider.switchActionState(null);
            }
            noticeWhiteMove();
        }
        else if (cur == 2) {
            if (blackSider.getSlotChesses().size() > 0) {
                blackSider.switchPutState();
            }
            else {
                blackSider.switchActionState(null);
            }
            whiteSider.switchWaitState();
            noticeBlackMove();
        }
    }

    //根据位置获取棋子
    private Chess getChessByPos(int row, int col) {
        for (Chess chess : chessList) {
            if (chess.row == row && chess.col == col) {
                return chess;
            }
        }
        return null;
    }

    /**
     * 对弈双方的各种信息
     */
    private static class Sider {

        /**
         * 《夺势棋》9x9棋盘，第一行做黑棋棋槽，最后一行做白棋棋槽
         */
        public static final int[][] SEIZE_POWER_CHESS_STYLE = {
                {0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0}
        };
        /**
         * 黑棋棋槽所在行
         */
        public static final int BLACK_SLOT_ROW = 0;
        /**
         * 白棋棋槽所在行
         */
        public static final int WHITE_SLOT_ROW = SEIZE_POWER_CHESS_STYLE.length - 1;
        /**
         * 等待对面行动状态
         */
        public static final int STATE_WAIT = 0;
        /**
         * 选择落子状态
         */
        public static final int STATE_PUT = 1;
        /**
         * 棋子行动状态
         */
        public static final int STATE_ACTION = 2;

        private SeizePowerChessRoom room; //上下文环境
        private int side;//归属黑棋还是白棋 1黑  2白
        private int stateFlag; //状态标志，0：等待对面行动， 1：选择落子状态， 2：棋子行动状态。
        private boolean hasStar; //是否设定了标星的棋子

        public Sider(SeizePowerChessRoom room, int side) {
            this.room = room;
            this.side = side;
        }


        /**
         * 初始化棋盘样式
         */
        public static void initChessBoardStyle(SeizePowerChessRoom room) {
            room.originGrids = SEIZE_POWER_CHESS_STYLE;
            room.curGrids = GridsUtils.copyGrids(room.originGrids);
            room.chessboardStyle = new ArrayList<>();
            int row = room.curGrids.length;
            int col = room.curGrids[0].length;

            //画棕色外边框
            room.chessboardStyle.add(new GroundSign(room.getIndex(0, 0), room.getIndex(row - 1, col - 1), "#00DDAA99", "#FFAA6622", 2.5f, 0, 0));

            //画棋槽边框
            room.chessboardStyle.add(new GroundSign(room.getIndex(BLACK_SLOT_ROW, 0), room.getIndex(BLACK_SLOT_ROW, col - 1), "#FFC9C2A7", "#FFAA6622", 2.5f, 0, 0));
            room.chessboardStyle.add(new GroundSign(room.getIndex(WHITE_SLOT_ROW, 0), room.getIndex(WHITE_SLOT_ROW, col - 1), "#FFC9C2A7", "#FFAA6622", 2.5f, 0, 0));
        }

        /**
         * 初始创建和摆放棋子
         */
        public static void initChesses(SeizePowerChessRoom room) {
            room.chessList.add(new Chess(room, room.blackSider, 4, 1, 3, 3, BLACK_SLOT_ROW, 0)); //高攻高速影刺客
            room.chessList.add(new Chess(room, room.blackSider, 4, 2, 2, 3, BLACK_SLOT_ROW, 1)); //中规中矩轻骑兵
            room.chessList.add(new Chess(room, room.blackSider, 4, 3, 3, 1, BLACK_SLOT_ROW, 2)); //长手短腿弓箭手
            room.chessList.add(new Chess(room, room.blackSider, 5, 2, 2, 2, BLACK_SLOT_ROW, 3)); //均衡存乎万物间
            room.chessList.add(new Chess(room, room.blackSider, 5, 2, 3, 2, BLACK_SLOT_ROW, 4)); //力大飞砖狂战士
            room.chessList.add(new Chess(room, room.blackSider, 5, 3, 2, 3, BLACK_SLOT_ROW, 5)); //长手长脚强战力
            room.chessList.add(new Chess(room, room.blackSider, 6, 2, 1, 1, BLACK_SLOT_ROW, 6)); //高血低能当诱饵
            room.chessList.add(new Chess(room, room.blackSider, 6, 1, 2, 3, BLACK_SLOT_ROW, 7)); //高血短手重骑兵
            room.chessList.add(new Chess(room, room.blackSider, 6, 1, 1, 3, BLACK_SLOT_ROW, 8)); //强脚弱手骚扰怪

            room.chessList.add(new Chess(room, room.whiteSider, 4, 1, 3, 3, WHITE_SLOT_ROW, 0)); //高攻高速影刺客
            room.chessList.add(new Chess(room, room.whiteSider, 4, 2, 2, 3, WHITE_SLOT_ROW, 1)); //中规中矩轻骑兵
            room.chessList.add(new Chess(room, room.whiteSider, 4, 3, 3, 1, WHITE_SLOT_ROW, 2)); //长手短腿弓箭手
            room.chessList.add(new Chess(room, room.whiteSider, 5, 2, 2, 2, WHITE_SLOT_ROW, 3)); //均衡存乎万物间
            room.chessList.add(new Chess(room, room.whiteSider, 5, 2, 3, 2, WHITE_SLOT_ROW, 4)); //力大飞砖狂战士
            room.chessList.add(new Chess(room, room.whiteSider, 5, 3, 2, 3, WHITE_SLOT_ROW, 5)); //长手长脚强战力
            room.chessList.add(new Chess(room, room.whiteSider, 6, 2, 1, 1, WHITE_SLOT_ROW, 6)); //高血低能当诱饵
            room.chessList.add(new Chess(room, room.whiteSider, 6, 1, 2, 3, WHITE_SLOT_ROW, 7)); //高血短手重骑兵
            room.chessList.add(new Chess(room, room.whiteSider, 6, 1, 1, 3, WHITE_SLOT_ROW, 8)); //强脚弱手骚扰怪
        }

        /**
         * 切换到等待状态
         */
        public void switchWaitState() {
            stateFlag = STATE_WAIT;
            for (Chess chess : room.chessList) {
                if (chess.side == this) {//只影响自己一方的棋子
                    chess.isActioned = true; //都切换为“已经行动过”状态，就不会绘制绿框了，也不会响应触摸
                }
            }
        }

        /**
         * 切换到落子状态
         */
        public void switchPutState() {
            stateFlag = STATE_PUT;
            for (Chess chess : room.chessList) {
                if (chess.side == this) {//只影响自己一方的棋子
                    if (isChessInSlot(chess)) { //棋槽中的棋子都切换到可以响应选择的状态
                        chess.isActioned = false;
                    }
                    else { //场上的棋子都不能响应
                        chess.isActioned = true;
                    }
                }
            }
        }

        /**
         * 切换到行动状态
         *
         * @param weak 刚落下的棋子，处于虚弱状态，当前回合不能行动
         */
        public void switchActionState(Chess weak) {
            stateFlag = STATE_ACTION;
            for (Chess chess : room.chessList) {
                if (chess.side == this) {//只影响自己一方的棋子
                    if (isChessInSlot(chess)) { //棋槽中的棋子不能在行动
                        chess.isActioned = true;
                    }
                    else {
                        if (chess == weak) { //刚落下的棋子，处于虚弱状态，当前回合不能行动
                            chess.isActioned = true;
                        }
                        else { //其它己方棋子可以响应选择
                            chess.isActioned = false;
                        }
                    }
                }
            }
        }

        /**
         * 尝试移动棋子
         */
        public void moveChess(int row, int col) {
            if (isCanMove(row, col)) {
                //实际移动行为
                room.choose.row = row;
                room.choose.col = col;
                room.choose.hp = room.choose.maxHp;//移动后生命值恢复满
                room.choose.isActioned = true;
                //如果是落子行为
                if (stateFlag == STATE_PUT) {
                    //初次落下的棋子标星
                    if (!hasStar) {
                        room.choose.isStar = true;
                        hasStar = true;
                    }
                    //对齐棋槽
                    alignmentSlot();
                    //切换到行动行为
                    switchActionState(room.choose);
                    if (isAllActioned()) {
                        room.choose = null;
                        room.changeSider(); //全部行动完了就换人
                    }
                    else {
                        room.choose = null;
                        room.noticeAllRefreshGameInfo();
                    }
                }
                //如果是行动行为
                else if (stateFlag == STATE_ACTION) {
                    if (isAllActioned()) {
                        room.choose = null;
                        room.changeSider(); //全部行动完了就换人
                    }
                    else {
                        room.choose = null;
                        room.noticeAllRefreshGameInfo();
                    }
                }
                //基本上不可能的行为
                else {
                    room.choose = null;
                    room.noticeAllRefreshGameInfo();
                }
            }
        }

        /**
         * 尝试攻击目标棋子
         */
        public void attackChess(Chess target) {
            if (isCanAttack(target.row, target.col)) {
                room.choose.isActioned = true;
                target.hp -= room.choose.atk; //攻击伤害计算
                if (target.hp <= 0) {
                    target.side = room.choose.side; //击败俘虏对方棋子
                    target.hp = target.maxHp; //生命值恢复
                    target.row = this.side == 1 ? BLACK_SLOT_ROW : WHITE_SLOT_ROW;
                    alignmentSlot();
                }
                if (isWin()) {
                    room.choose = null;
                    room.gameOver(this);
                }
                else {
                    if (isAllActioned()) {
                        room.choose = null;
                        room.changeSider(); //全部行动完了就换人
                    }
                    else {
                        room.choose = null;
                        room.noticeAllRefreshGameInfo();
                    }
                }
            }
        }

        //判断该方是否获胜
        private boolean isWin() {
            Sider otherSider = room.getOtherSider();
            int count = 0;
            boolean starLive = false;
            for (Chess chess : room.chessList) {
                if (chess.side == otherSider) {
                    count++;
                    if (chess.isStar) {
                        starLive = true;
                    }
                }
            }
            return count < 5 || !starLive;
        }

        /**
         * 棋槽中剩余的棋子全部左对齐
         */
        private void alignmentSlot() {
            List<Chess> slotChesses = getSlotChesses();
            for (int i = 0; i < slotChesses.size(); i++) {
                slotChesses.get(i).col = i;
            }
        }

        /**
         * 获取己方棋槽中的所有棋子
         */
        private List<Chess> getSlotChesses() {
            List<Chess> slotChesses = new ArrayList<>();
            for (Chess chess : room.chessList) {
                if (chess.side == this && isChessInSlot(chess)) {
                    slotChesses.add(chess);
                }
            }
            return slotChesses;
        }

        //判断该棋子是否在棋槽中
        private boolean isChessInSlot(Chess chess) {
            return chess.row == BLACK_SLOT_ROW || chess.row == WHITE_SLOT_ROW;
        }

        //全部行动完毕，没有可以再选中的棋子了
        private boolean isAllActioned() {
            for (Chess chess : room.chessList) {
                if (!chess.isActioned) {
                    return false;
                }
            }
            return true;
        }

        //判断当前选中的棋子是否能够移动到选中的坐标
        private boolean isCanMove(int row, int col) {
            List<int[]> canMovedPosList = room.choose.getCanMovedPos();
            if (canMovedPosList != null && canMovedPosList.size() > 0) {
                for (int[] pos : canMovedPosList) {
                    if (pos[0] == row && pos[1] == col) { //目标位置坐标在选中棋子的可移动范围内
                        return true;
                    }
                }
            }
            return false;
        }

        //判断当前选中的棋子是否能够攻击到选中的坐标
        private boolean isCanAttack(int row, int col) {
            List<int[]> canAttackPosList = room.choose.getCanAttackPos();
            if (canAttackPosList != null && canAttackPosList.size() > 0) {
                for (int[] pos : canAttackPosList) {
                    if (pos[0] == row && pos[1] == col) {
                        return true;
                    }
                }
            }
            return false;
        }

    }


    /**
     * 棋子的模型
     */
    public static class Chess {
        private SeizePowerChessRoom room; //上下文游戏环境
        public Sider side; //归属
        public boolean isStar; //是否为标星棋子
        public final int maxHp; //最大生命值
        public int hp; //生命值 5-7
        public int rng; //射程 1-3
        public int atk; //攻击力 1-3
        public int sp; //移动速度 1-3

        public int row; //棋子在棋盘上的坐标
        public int col;//棋子在棋盘上的坐标
        public boolean isActioned; //本回合是否行动过

        public Chess(SeizePowerChessRoom room, Sider side, int hp, int rng, int atk, int sp, int row, int col) {
            this.room = room;
            this.side = side;
            this.isStar = false;
            this.maxHp = hp;
            this.hp = hp;
            this.rng = rng;
            this.atk = atk;
            this.sp = sp;
            this.row = row;
            this.col = col;
            this.isActioned = false;
        }

        /**
         * 获取该棋子可移动范围格子列表
         */
        public List<int[]> getCanMovedPos() {
            List<int[]> canMovedPosList = new ArrayList<>();
            int h = room.curGrids.length;
            int w = room.curGrids[0].length;
            if (side.stateFlag == Sider.STATE_PUT) {
                for (int i = 1; i < h - 1; i++) {
                    for (int j = 0; j < w; j++) {
                        if (room.curGrids[i][j] == 0) { //落子状态下任意空格都可以落下
                            canMovedPosList.add(new int[]{i, j});
                        }
                    }
                }
            }
            else if (side.stateFlag == Sider.STATE_ACTION) {
                int[] originPoint = new int[]{row, col};
                canMovedPosList.add(originPoint); //原位置也能落下
                int dis = 1;
                while (dis <= sp) { //由原位置向外扩展搜索三次
                    moveSearch(originPoint, canMovedPosList, dis);
                    dis++;
                }
            }
            return duplicateList(canMovedPosList); //去重后返回
        }

        /**
         * 获取该棋子可攻击范围格子列表
         */
        public List<int[]> getCanAttackPos() {
            List<int[]> canAttackPosList = new ArrayList<>();
            List<int[]> canMovedPosList = new ArrayList<>();
            if (side.stateFlag == Sider.STATE_ACTION) {
                int[] originPoint = new int[]{row, col};
                canMovedPosList.add(originPoint); //原位置也能落下
                int dis = 1;
                while (dis <= rng) {
                    List<int[]> attackList = attackSearch(originPoint, canMovedPosList, dis);
                    canAttackPosList.addAll(attackList);
                    dis++;
                }
            }
            return duplicateList(canAttackPosList);
        }

        //移动路径搜索
        private void moveSearch(int[] target, List<int[]> canMovedPosList, int dis) {
            List<int[]> addList = new ArrayList<>();
            for (int[] ints : canMovedPosList) {
                if (getDistance(target, ints) == dis - 1) { //只有最外面一圈的有资格扩展
                    List<int[]> aroundList = getAroundList(ints); //获取每个格子周围一圈的格子
                    for (int[] ints1 : aroundList) {
                        if (isInMap(ints1) && getDistance(target, ints1) == dis && room.curGrids[ints1[0]][ints1[1]] == 0) { //再把不符合要求的格子排除掉
                            addList.add(ints1);
                        }
                    }
                }
            }
            canMovedPosList.addAll(addList);
        }

        //攻击路径搜索
        private List<int[]> attackSearch(int[] target, List<int[]> canMovedPosList, int dis) {
            List<int[]> attackList = new ArrayList<>();
            List<int[]> addList = new ArrayList<>();
            for (int[] ints : canMovedPosList) {
                if (getDistance(target, ints) == dis - 1) {
                    List<int[]> aroundList = getAroundList(ints);
                    for (int[] ints1 : aroundList) {
                        if (isInMap(ints1) && getDistance(target, ints1) == dis) {
                            if (room.curGrids[ints1[0]][ints1[1]] == 0) {
                                addList.add(ints1);
                            }
                            else {
                                if (room.curGrids[ints1[0]][ints1[1]] != side.side) {
                                    attackList.add(ints1);
                                }
                            }
                        }
                    }
                }
            }
            canMovedPosList.addAll(addList);
            return attackList;
        }

        //去除List列表中重复值方法一：普通的方法,利用for循环去重
        private List<int[]> duplicateList(List<int[]> list) {
            for (int i = 0; i < list.size() - 1; i++) {
                for (int j = list.size() - 1; j > i; j--) {
                    int[] item = list.get(i);
                    int[] jtem = list.get(j);
                    if (item[0] == jtem[0] && item[1] == jtem[1]) {
                        list.remove(j);
                    }
                }
            }
            return list;
        }

        //判断棋子是否在棋盘中而不是棋槽中
        private boolean isInMap(int[] point) {
            return point[0] > Sider.BLACK_SLOT_ROW && point[0] < Sider.WHITE_SLOT_ROW && point[1] >= 0 && point[1] <= room.curGrids[0].length - 1;
        }

        /**
         * 获取某个格子坐标四周的格子坐标列表
         */
        private List<int[]> getAroundList(int[] ints) {
            List<int[]> aroundList = new ArrayList<>();
            aroundList.add(new int[]{ints[0] - 1, ints[1]});
            aroundList.add(new int[]{ints[0] + 1, ints[1]});
            aroundList.add(new int[]{ints[0], ints[1] - 1});
            aroundList.add(new int[]{ints[0], ints[1] + 1});
            return aroundList;
        }

        /**
         * 获取两个坐标之间的距离长度，直向一格一格的数
         */
        private int getDistance(int[] target, int[] ints) {
            return Math.abs(target[0] - ints[0]) + Math.abs(target[1] - ints[1]);
        }

    }
}
